package instructions;

import base.Environment;
import base.Identifier;

public class Local implements Instruction {

	private Identifier identifier;
	private Instruction instruction;
	
	/**
	 * Creates the local instruction:
	 * local(identifier) {
	 * 		instruction
	 * }
	 */
	public Local(Identifier identifier, Instruction instruction) {		
		this.identifier = identifier;
		this.instruction = instruction;
	}
	
	/**
	 * Executes the local: adds identifier to the environment, or replaces its present value by a null value and executes the instruction
	 * Then, it regenerates the old environment with the eventual changes to non-local identifiers
	 */
	public Environment instr(Environment env) throws BadInstructionException {
		
		Environment newEnv = env.clone(), resultEnv;
		
		if (env.contains(this.identifier))
			newEnv.update(this.identifier, null);
		else
			newEnv.add(this.identifier);
		
		resultEnv = instruction.instr(newEnv);
		
		if (env.contains(this.identifier))
			resultEnv.update(this.identifier, env.getValue(this.identifier));
		else
			resultEnv.remove(this.identifier);
		
		return resultEnv;
	}
	
}
